/* Copyright 2013 ESRI
* 
* All rights reserved under the copyright laws of the United States
* and applicable international laws, treaties, and conventions.
* 
* You may freely redistribute and use this sample code, with or
* without modification, provided you include the original copyright
* notice and use restrictions.
* 
* See the use restrictions at <your ArcGIS install location>/DeveloperKit10.2/userestrictions.txt.
* 
*/
package arcgissamples.geoprocessing;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;

import com.esri.arcgis.geoprocessing.GeoProcessor;
import com.esri.arcgis.geoprocessing.tools.datamanagementtools.CopyFeatures;
import com.esri.arcgis.geoprocessing.tools.datamanagementtools.MakeFeatureLayer;
import com.esri.arcgis.geoprocessing.tools.datamanagementtools.SelectLayerByAttribute;
import com.esri.arcgis.geoprocessing.tools.datamanagementtools.SelectLayerByLocation;
import com.esri.arcgis.system.AoInitialize;
import com.esri.arcgis.system.EngineInitializer;
import com.esri.arcgis.system.esriLicenseProductCode;
import com.esri.arcgis.system.esriLicenseStatus;

public class CopyFeaturesFromLayer
{
	String inputDir, outputDir;
	GeoProcessor gp = null;

	/**
	 * default constructor
	 */
	public CopyFeaturesFromLayer()
	{
		//Get DEVKITHOME Home
		String devKitHome = System.getenv("AGSDEVKITJAVA");
		
		inputDir = devKitHome + "java" + File.separator + "samples" + File.separator
				+ "data" + File.separator + "geoprocessing";

		// Verify that output folder exists. If it already exists, clean it, delete
		// it and re-create it. If it does not exist, create it.
		outputDir = getOutputDir() + File.separator + "gpexectools";
		cleanAndRecreateDirectory(outputDir);
		
		System.out.print("\n**Creating GeoProcessor object...");
		try
		{
			gp = new GeoProcessor();
		}
		catch (UnknownHostException e)
		{
			e.printStackTrace();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		System.out.println("done.");

	}

	public static void main(String[] args)
	{
		System.out.println("Starting CreateFeatureClass - An ArcObjects Java SDK Developer Sample");
		
		try
		{
			// Initialize the engine and licenses.
			EngineInitializer.initializeEngine();

			AoInitialize aoInit = new AoInitialize();
			initializeArcGISLicenses(aoInit);
			
			CopyFeaturesFromLayer gpex = new CopyFeaturesFromLayer();
			gpex.executeTools();

			/*
			 * Release license
			 */
			System.out.print("\n**Releasing license...");
			aoInit.shutdown();
			
			// Do not make any call to ArcObjects after ShutDownApplication()
			EngineInitializer.releaseAll();
			System.out.println("done.");
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * Creates a mosaic in Raster Catalog
	 * 
	 * @throws Exception
	 */
	public void executeTools() throws Exception
	{
		/*
		 * Initialize
		 */
		String wellLayerName = "wellsLayer";
		String bedrockLayerName = "bedrockLayer";

		/*
		 * STEP 1: Make feature layers using the MakeFeatureLayer tool for the inputs to the SelectByLocation tool.
		 */
		System.out.print("\n**Creating feature layers in memory using Data Management/MakeFeatureLayer GP tool...");
		MakeFeatureLayer makeFeatureLayer = new MakeFeatureLayer();
		makeFeatureLayer.setInFeatures(inputDir + File.separator + "wells.shp");
		makeFeatureLayer.setOutLayer(wellLayerName);
		gp.execute(makeFeatureLayer, null);

		makeFeatureLayer.setInFeatures(inputDir + File.separator + "bedrock.shp");
		makeFeatureLayer.setOutLayer(bedrockLayerName);
		gp.execute(makeFeatureLayer, null);
		System.out.println("done.");

		/*
		 * STEP 2: Execute SelectLayerByLocation using the feature layers to select all wells that intersect theb
		 * bedrock geololgy.
		 */
		System.out.print("\n**Selecting all wells that intersect bedrock geology, using Data Management/SelectLayerByLocation...");
		SelectLayerByLocation selectByLocation = new SelectLayerByLocation();
		selectByLocation.setInLayer(wellLayerName);
		selectByLocation.setSelectFeatures(bedrockLayerName);
		selectByLocation.setOverlapType("INTERSECT");
		gp.execute(selectByLocation, null);
		System.out.println("done.");

		/*
		 * STEP 3: Execute SelectLayerByAttribute to select all wells that have a well yield > 150 L/min.
		 */
		System.out.print("\n**Selecting all wells that have a well yield > 150 L/min using Data Management/SelectLayerByAttribute GP tool...");
		SelectLayerByAttribute selectByAttribute = new SelectLayerByAttribute();
		selectByAttribute.setInLayerOrView(wellLayerName);
		selectByAttribute.setSelectionType("NEW_SELECTION");
		selectByAttribute.setWhereClause("WELL_YIELD > 150");
		gp.execute(selectByAttribute, null);
		System.out.println("done.");

		/*
		 * STEP 4: Execute CopyFeatures tool to create a new feature class of wells with well yield > 150 L/min.
		 */
		System.out.print("\n**Executing Data Management/CopyFeatures tool to create a new feature class of wells with well yield > 150 L/min...");
		CopyFeatures copyFeatures = new CopyFeatures();
		copyFeatures.setInFeatures(wellLayerName);
		copyFeatures.setOutFeatureClass(outputDir + File.separator + "wellsCopy.shp");
		// Set the output Coordinate System environment
		String coordSysPath = inputDir + File.separator + "NAD 1983 UTM Zone 21N.prj";
		gp.setEnvironmentValue("outputCoordinateSystem", coordSysPath);
		gp.execute(copyFeatures, null);
		System.out.println("done.");
	}

	/**
	 * Initializes the lowest available ArcGIS License
	 */
	private static void initializeArcGISLicenses(AoInitialize aoInit)
	{
		try
		{
			if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) 
					== esriLicenseStatus.esriLicenseAvailable)
			{
				aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeEngine);
			}
			else if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeBasic) 
					== esriLicenseStatus.esriLicenseAvailable)
			{
				aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeBasic);
			}
			else
			{
				System.err.println("Could not initialize an Engine or Basic License. Exiting application.");
				System.exit(-1);
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * Returns the output directory
	 * 
	 * @param testClass
	 * @return
	 */
	public String getOutputDirectoryPath()
	{
		try
		{
			ClassLoader cl = this.getClass().getClassLoader();
			String packageName = this.getClass().getPackage().getName();
			String packageStructure = packageName.replace('.', File.separatorChar);

			URI uri = new URI(cl.getResource(packageStructure).toExternalForm());
			String absPath = new File(uri).getAbsolutePath();

			return absPath + File.separator + "output";
		}
		catch (URISyntaxException e)
		{
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * Empties specified directory of all files, deletes and re-creates it
	 * 
	 * @param dirName
	 *            String
	 */
	public void cleanAndRecreateDirectory(String dirName)
	{
		cleanAndDeleteDirectory(dirName);
		File dir = new File(dirName);
		dir.mkdir();
	}

	/**
	 * Deletes all files in specified directory and then deletes the directory as well
	 * 
	 * @param Path
	 *            String
	 */
	public void cleanAndDeleteDirectory(String Path)
	{
		File src = new File(Path);
		if (src.isDirectory() && src.exists())
		{
			File list[] = src.listFiles();
			for (int i = 0; i < list.length; i++)
			{
				if (list[i].isDirectory())
				{
					cleanAndDeleteDirectory(list[i].getPath());
					list[i].delete();
				}
				else
				{
					list[i].delete();
				}
			}
			src.delete();
		}
		else
		{
			src.delete();
		}
	}

	/**
	 * Returns output directory
	 * 
	 * @return
	 */
	private static String getOutputDir()
	{
		String userDir;
		if (System.getProperty("os.name").toLowerCase().indexOf("win") > -1)
			userDir = System.getenv("UserProfile");
		else
			userDir = System.getenv("HOME");
		String outputDir = userDir + File.separator + "arcgis_sample_output";
		System.out.println("Creating output directory - " + outputDir);
		new File(outputDir).mkdir();
		return outputDir;

	}
}
